import 'dart:typed_data';

import 'package:bluetooth_protocols_plugin/src/lorin/base/lorin_constant.dart';
import 'package:bluetooth_protocols_plugin/src/tools/utils.dart';
import '../../base/cmd/lorin_cmd_base.dart';
import '../../../base/enum.dart';
import '../lorin_request_body.dart';

// Lorin私有请求体
abstract class LorinPrivateRequestBody<C extends LorinCmdBase> {
  // 基础指令
  C get cmdBase;

  // 数据fromat
  final LorinDataFormatType dataFormat = LorinDataFormatType.speStcp;

  // 默认目标设备
  int get defaultTargetDevice;

  // 获取实时信息
  LorinRequestBody getRealtimeInfo() => LorinRequestBody(
        "GetRealtimeInfo",
        dataFormat: dataFormat,
        cmd: cmdBase.realtimeInfoCmd,
        target: defaultTargetDevice,
      );

  // 获取实时状态
  LorinRequestBody getRealtimeStatus() => LorinRequestBody(
        "GetRealtimeStatus",
        dataFormat: dataFormat,
        cmd: cmdBase.realtimeStatusCmd,
        target: defaultTargetDevice,
      );

  // 获取实时错误
  LorinRequestBody getRealtimeError() => LorinRequestBody(
        "GetRealtimeError",
        dataFormat: dataFormat,
        cmd: cmdBase.realtimeErrorCmd,
        target: defaultTargetDevice,
      );

  // 获取所有实时信息
  LorinRequestBody getRealtimeAll() => LorinRequestBody(
        "GetRealtimeAll",
        dataFormat: dataFormat,
        cmd: cmdBase.realtimeAllCmd,
        target: defaultTargetDevice,
      );

  // 获取实时电池信息
  LorinRequestBody getRealtimeBatteryInfo() => LorinRequestBody(
        "GetRealtimeBatteryInfo",
        dataFormat: dataFormat,
        cmd: cmdBase.realtimeBatteryInfoCmd,
        target: defaultTargetDevice,
      );

  // 获取单次统计
  LorinRequestBody getStatisticOnce({int? startNum, int? count}) =>
      LorinRequestBody(
        "GetStatisticOnce",
        dataFormat: dataFormat,
        cmd: cmdBase.statisticOnceCmd,
        target: defaultTargetDevice,
        param: startNum != null && count != null
            ? Uint8List.fromList([startNum, count])
            : null,
        isWrite: false,
      );

  // 获取总统计
  LorinRequestBody getStatisticTotal() => LorinRequestBody(
        "GetStatisticTotal",
        dataFormat: dataFormat,
        cmd: cmdBase.statisticTotalCmd,
        target: defaultTargetDevice,
      );

  // 获取综合设置
  LorinRequestBody getSettingsAll() => LorinRequestBody(
        "GetSettingsAll",
        dataFormat: dataFormat,
        cmd: cmdBase.settingsAllCmd,
        target: defaultTargetDevice,
      );

  // 开锁/解锁
  LorinRequestBody lock([bool isLock = true]) {
    return LorinRequestBody(
      "Lock",
      dataFormat: dataFormat,
      cmd: cmdBase.lockCmd,
      param: Uint8List.fromList([isLock ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 获取综合实时信息
  LorinRequestBody getIntegratedRealtimeInfoAll() {
    return LorinRequestBody(
      "GetIntegratedRealtimeInfoAll",
      dataFormat: dataFormat,
      cmd: cmdBase.integratedRealtimeInfoAllCmd,
      target: defaultTargetDevice,
    );
  }

  // 获取综合产品信息
  LorinRequestBody getIntegratedProductInfo() {
    return LorinRequestBody(
      "GetIntegratedProductInfo",
      dataFormat: dataFormat,
      cmd: cmdBase.integratedProductInfoCmd,
      target: defaultTargetDevice,
    );
  }

  // 设置周期数据上报间隔
  LorinRequestBody setPeriodicDataReportingInterval(int interval) {
    return LorinRequestBody(
      "SetPeriodicDataReportingInterval",
      dataFormat: dataFormat,
      cmd: cmdBase.setPeriodicDataReportingIntervalCmd,
      param: Uint8List.fromList([interval]),
      target: defaultTargetDevice,
    );
  }

  // 鸣笛
  LorinRequestBody horn() {
    return LorinRequestBody(
      "Horn",
      dataFormat: dataFormat,
      cmd: cmdBase.playSoundEffectCmd,
      param: Uint8List.fromList([24, 1]),
      target: defaultTargetDevice,
    );
  }

  // 播放指定音效 uint8_t  audio_index + uint8_t  0 终止  1播放
  LorinRequestBody playSound(int audioIndex, {bool? play = true}) {
    return LorinRequestBody(
      "PlaySoundEffect",
      dataFormat: dataFormat,
      cmd: cmdBase.playSoundEffectCmd,
      param: Uint8List.fromList([audioIndex, play == true ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 灯光
  LorinRequestBody light({required bool lowBeam, required bool highBeam}) {
    return LorinRequestBody(
      "Light",
      dataFormat: dataFormat,
      cmd: cmdBase.lightCmd,
      param: Uint8List.fromList([lowBeam ? 1 : 0, highBeam ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 车辆昵称
  LorinRequestBody getVehicleNickname() {
    return LorinRequestBody(
      "GetVehicleNickname",
      dataFormat: dataFormat,
      cmd: cmdBase.vehicleNicknameCmd,
      target: LorinConstant.eucBluetoothDevice,
    );
  }

  // 车辆昵称
  LorinRequestBody setVehicleNickname({required Uint8List nicknameBytes}) {
    return LorinRequestBody(
      "SetVehicleNickname",
      dataFormat: dataFormat,
      cmd: cmdBase.vehicleNicknameCmd,
      param: nicknameBytes,
      target: LorinConstant.eucBluetoothDevice,
    );
  }

  // 车辆密码
  LorinRequestBody getVehiclePassword() {
    return LorinRequestBody(
      "GetVehiclePassword",
      dataFormat: dataFormat,
      cmd: cmdBase.vehiclePasswordCmd,
      target: LorinConstant.eucBluetoothDevice,
      param: Uint8List.fromList([1]),
      isWrite: false,
    );
  }

  // 车辆密码
  LorinRequestBody setVehiclePassword({required Uint8List passwordBytes}) {
    return LorinRequestBody(
      "SetVehiclePassword",
      dataFormat: dataFormat,
      cmd: cmdBase.vehiclePasswordCmd,
      param: Uint8List.fromList([1, passwordBytes.length, ...passwordBytes]),
      target: LorinConstant.eucBluetoothDevice,
    );
  }

  // 设置限速
  LorinRequestBody setSpeedLimit(int speed) {
    return LorinRequestBody(
      "SetSpeedLimit",
      dataFormat: dataFormat,
      cmd: cmdBase.speedLimitCmd,
      param: Utils.intTo2Bytes(speed, endian: Endian.little),
      target: defaultTargetDevice,
    );
  }

  // 设置告警速度
  LorinRequestBody setWarningSpeed(int speed) {
    return LorinRequestBody(
      "SetWarningSpeed",
      dataFormat: dataFormat,
      cmd: cmdBase.alarmSpeedCmd,
      param: Uint8List.fromList([
        ...Utils.intTo2Bytes(speed - 1, endian: Endian.little),
        ...Utils.intTo2Bytes(speed, endian: Endian.little)
      ]),
      target: defaultTargetDevice,
    );
  }

  // 设置骑行模式
  LorinRequestBody setRideMode(int mode) {
    final int v = mode.clamp(0, 255);
    return LorinRequestBody(
      "SetRideMode",
      dataFormat: dataFormat,
      cmd: cmdBase.rideModeCmd,
      param: Uint8List.fromList([v]),
      target: defaultTargetDevice,
    );
  }

  // 骑行辅助开关
  LorinRequestBody setRideAssistSwitch(bool enabled) {
    return LorinRequestBody(
      "SetRideAssistSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.rideAssistSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 加、减速辅助百分比
  LorinRequestBody setAccAndBrakeAssistPercentage(
      int accPercentage, int brakePercentage) {
    final int accValue = accPercentage.clamp(0, 100);
    final int brakeValue = brakePercentage.clamp(0, 100);
    return LorinRequestBody(
      "SetAccAndBrakeAssistPercentage",
      dataFormat: dataFormat,
      cmd: cmdBase.accAndBrakeAssistPercentageCmd,
      param: Uint8List.fromList([accValue, brakeValue]),
      target: defaultTargetDevice,
    );
  }

  // 踏板灵敏度
  LorinRequestBody setPedalSensitivity(int sensitivity1, int sensitivity2) {
    final int v1 = sensitivity1.clamp(0, 100);
    final int v2 = sensitivity2.clamp(0, 100);
    return LorinRequestBody(
      "SetPedalSensitivity",
      dataFormat: dataFormat,
      cmd: cmdBase.pedalSensitivityCmd,
      param: Uint8List.fromList([v1, v2]),
      target: defaultTargetDevice,
    );
  }

  // 平衡角度
  LorinRequestBody setBalanceAngle(int angle) {
    return LorinRequestBody(
      "SetBalanceAngle",
      dataFormat: dataFormat,
      cmd: cmdBase.balanceAngleCmd,
      param: Utils.intTo2Bytes(angle, endian: Endian.little),
      target: defaultTargetDevice,
    );
  }

  // 赛道倾斜角度模式开关
  LorinRequestBody setBermAngleModeSwitch(bool enabled) {
    return LorinRequestBody(
      "SetBermAngleModeSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.bermAngleModeSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 防飞转开关
  LorinRequestBody setSpinKillSwitch(bool enabled) {
    return LorinRequestBody(
      "SetSpinKillSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.spinKillSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 设置RTC时间 (year offset from 2000)
  /*
          typedef struct{
            uint32_t year   : 6; // 2020-2084
            uint32_t month  : 4; // 1-12
            uint32_t day    : 5; // 1-31
            uint32_t hour   : 5; // 0-23
            uint32_t minute : 6; // 0-59
            uint32_t second : 6; // 0-59
          }RTC_DATE_TIME;
        */
  LorinRequestBody setRtcTime(DateTime time) {
    return LorinRequestBody(
      "SetRtcTime",
      dataFormat: dataFormat,
      cmd: cmdBase.rtcTimeCmd,
      param: Utils.dateTimeToBytes(time),
      target: defaultTargetDevice,
    );
  }

  // 设置待机时长
  LorinRequestBody setStandyTime(int time) {
    int temp = time < 0 ? 0 : (time > 64800 ? 64800 : time);
    return LorinRequestBody(
      "SetStandyTime",
      dataFormat: dataFormat,
      cmd: cmdBase.standbyTimeCmd,
      param: Utils.intTo2Bytes(temp, endian: Endian.little),
      target: defaultTargetDevice,
    );
  }

  // 主动声浪开关
  LorinRequestBody setMainSoundSwitch(bool enabled) {
    return LorinRequestBody(
      "setMainSoundSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.mainSoundSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 语音开关
  LorinRequestBody setVoiceSwitch(bool enabled) {
    return LorinRequestBody(
      "setVoiceSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.audioSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 音量大小
  LorinRequestBody setVolume(int volume) {
    final int v = volume.clamp(0, 100);
    return LorinRequestBody(
      "SetVolume",
      dataFormat: dataFormat,
      cmd: cmdBase.volumeCmd,
      param: Uint8List.fromList([v]),
      target: defaultTargetDevice,
    );
  }

  // 云盒低电唤醒车辆开关
  LorinRequestBody setTBoxLowBatteryWakeupSwitch(bool enabled) {
    return LorinRequestBody(
      "setTBoxLowBatteryWakeupSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.tBoxLowPowerWakeupCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 云盒重启
  /*
    typedef ARM_PACKED struct{
        uint16_t format;                    /**< 数据格式，固定为1 */
        uint8_t reboot_mode;                /**< 重启方式，参见 TBOX_REBOOT_MODE */
    }GNUC_PACKED TBOX_REBOOT_CMD

    typedef enum{
        TBOX_MODE_SOFT                 = 0,       /** 软重启 */
        TBOX_MODE_HARD                 = 1,       /** 硬重启 */
        TBOX_MODE_RECONNECT_AP         = 1,       /** 软重启，重启后重连accesspoint */
    }TBOX_REBOOT_MODE;
  */
  LorinRequestBody tBoxReboot() {
    return LorinRequestBody("TBoxReboot",
        dataFormat: dataFormat,
        cmd: cmdBase.tBoxRebootCmd,
        target: LorinConstant.eucTBox,
        param: Uint8List.fromList([1, 0, 1]));
  }

  // 云盒信息显示开关
  LorinRequestBody setTBoxInfoDisplaySwitch(bool enabled) {
    return LorinRequestBody(
      "SetTBoxInfoDisplaySwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.tBoxInfoDisplaySwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 运输模式开关
  LorinRequestBody setTransportModeSwitch(bool enabled) {
    return LorinRequestBody(
      "SetTransportModeSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.transportModeSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 车辆较正
  LorinRequestBody triggerVehicleCalibration(
      {bool? gyroCalibrationEnabled,
      bool? pitchCalibrationEnabled,
      bool? rollCalibrationEnabled}) {
    return LorinRequestBody(
      "TriggerVehicleCalibration",
      dataFormat: dataFormat,
      cmd: cmdBase.vehicleCalibrationCmd,
      param: (gyroCalibrationEnabled == null &&
              pitchCalibrationEnabled == null &&
              rollCalibrationEnabled == null)
          ? null
          : Uint8List.fromList([
              gyroCalibrationEnabled == true ? 1 : 0,
              pitchCalibrationEnabled == true ? 1 : 0,
              rollCalibrationEnabled == true ? 1 : 0,
            ]),
      target: defaultTargetDevice,
    );
  }

  // 负载检测
  LorinRequestBody triggerLoadDetection() {
    return LorinRequestBody(
      "TriggerLoadDetection",
      dataFormat: dataFormat,
      cmd: cmdBase.loadDetectionCmd,
      target: defaultTargetDevice,
    );
  }

  // 空载检测
  LorinRequestBody triggerNoLoadDetection() {
    return LorinRequestBody(
      "TriggerNoLoadDetection",
      dataFormat: dataFormat,
      cmd: cmdBase.noLoadDetectionCmd,
      target: defaultTargetDevice,
    );
  }

  // 自动大灯模式开关
  LorinRequestBody setAutoHeadlightModeSwitch(bool enabled) {
    return LorinRequestBody(
      "SetAutoHeadlightModeSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.autoHeadlightModeSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 转向灯开关 (left, right)
  LorinRequestBody setTurnSignalLight(
      {required bool left, required bool right}) {
    return LorinRequestBody(
      "SetTurnSignalLight",
      dataFormat: dataFormat,
      cmd: cmdBase.turnSignalLightCmd,
      param: Uint8List.fromList([left ? 1 : 0, right ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 低电骑行开关
  LorinRequestBody setLowBatteryRideSwitch(bool enabled) {
    return LorinRequestBody(
      "SetLowBatteryRideSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.lowBatteryRideSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 显示屏自动熄屏
  LorinRequestBody setDisplayAutoOffSwitch(bool enabled) {
    return LorinRequestBody(
      "SetDisplayAutoOffSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.setDisplayAutoOffSwitch,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // logo灯亮度
  LorinRequestBody setLogoLightBrightness(int brightness) {
    final int v = brightness.clamp(0, 100);
    return LorinRequestBody(
      "SetLogoLightBrightness",
      dataFormat: dataFormat,
      cmd: cmdBase.logoLightBrightnessCmd,
      param: Uint8List.fromList([v]),
      target: defaultTargetDevice,
    );
  }

  // 获取搜索到的胎压传感器信息
  LorinRequestBody getTirePressureSensorInfo() {
    return LorinRequestBody(
      "GetTirePressureSensorInfo",
      dataFormat: dataFormat,
      cmd: cmdBase.tirePressureSensorInfoCmd,
      target: defaultTargetDevice,
      isWrite: false,
    );
  }

  // 清除搜索到的胎压传感器信息
  LorinRequestBody clearSearchedTirePressureSensorInfo() {
    return LorinRequestBody(
      "ClearSearchedTirePressureSensorInfo",
      dataFormat: dataFormat,
      cmd: cmdBase.tirePressureSensorInfoCmd,
      target: defaultTargetDevice,
      isWrite: true,
    );
  }

  // 胎压低压报警阈值
  LorinRequestBody setTirePressureLowAlarmThreshold(int threshold) {
    final int v = threshold.clamp(0, 255);
    return LorinRequestBody(
      "SetTirePressureLowAlarmThreshold",
      dataFormat: dataFormat,
      cmd: cmdBase.tirePressureLowAlarmThresholdCmd,
      param: Uint8List.fromList([v]),
      target: defaultTargetDevice,
    );
  }

  // 日行灯开关
  LorinRequestBody setDaytimeRunningLightSwitch(bool enabled) {
    return LorinRequestBody(
      "SetDaytimeRunningLightSwitch",
      dataFormat: dataFormat,
      cmd: cmdBase.daytimeRunningLightSwitchCmd,
      param: Uint8List.fromList([enabled ? 1 : 0]),
      target: defaultTargetDevice,
    );
  }

  // 显示屏进入升级状态
  LorinRequestBody displayEnterUpgradeStatus(bool enable) {
    return LorinRequestBody(
      "DisplayEnterUpgradeStatus",
      dataFormat: dataFormat,
      cmd: cmdBase.displayEnterUpgradeStatusCmd,
      target: LorinConstant.eucDisplay,
      param: Uint8List.fromList([enable ? 1 : 0]),
    );
  }

  // 显示屏进入文件传输状态
  LorinRequestBody displayEnterFileTransferStatus(bool enable) {
    return LorinRequestBody(
      "DisplayEnterFileTransferStatus",
      dataFormat: dataFormat,
      cmd: cmdBase.displayEnterFileTransferStatusCmd,
      target: LorinConstant.eucDisplay,
      param: Uint8List.fromList([enable ? 1 : 0]),
    );
  }

  // 开始电机自适应流程
  LorinRequestBody startMotorAdaptation() {
    return LorinRequestBody(
      "StartMotorAdaptation",
      dataFormat: dataFormat,
      cmd: cmdBase.startMotorAdaptationCmd,
      param: Uint8List.fromList([1, 1]),
      target: LorinConstant.eucDriver,
    );
  }

  // 查询电机自适应状态（例如是否正在适配、适配进度或结果）
  LorinRequestBody getMotorAdaptationStatus() {
    return LorinRequestBody(
      "GetMotorAdaptationStatus",
      dataFormat: dataFormat,
      cmd: cmdBase.getMotorAdaptationStatusCmd,
      target: LorinConstant.eucDriver,
    );
  }

  // 清除电机自适应（摩擦/偏差）相关存储数据
  LorinRequestBody clearMotorAdaptationData() {
    return LorinRequestBody(
      "ClearMotorAdaptationData",
      dataFormat: dataFormat,
      cmd: cmdBase.clearMotorAdaptationDataCmd,
      target: LorinConstant.eucDriver,
      param: Uint8List.fromList([1, 1]),
    );
  }

  // 停止正在进行的电机自适应流程
  LorinRequestBody stopMotorAdaptation() {
    return LorinRequestBody(
      "StopMotorAdaptation",
      dataFormat: dataFormat,
      cmd: cmdBase.stopMotorAdaptationCmd,
      target: LorinConstant.eucDriver,
      isWrite: true,
    );
  }

  // 启动电机自检（硬件/传感器/驱动器自检）
  LorinRequestBody startMotorSelfCheck({int? method}) {
    return LorinRequestBody(
      "StartMotorSelfCheck",
      dataFormat: dataFormat,
      cmd: cmdBase.startMotorSelfCheckCmd,
      target: LorinConstant.eucDriver,
      param: method != null ? Uint8List.fromList([method]) : null,
    );
  }

  // 开始电池电压校准流程
  LorinRequestBody startBatteryVoltageCalibration({bool? write = true}) {
    return LorinRequestBody(
      "StartBatteryVoltageCalibration",
      dataFormat: dataFormat,
      cmd: cmdBase.startBatteryVoltageCalibrationCmd,
      target: LorinConstant.eucDriver,
      isWrite: write == true,
    );
  }
}
